<?php

namespace DreamCat\ChanPool\Impl;


use DreamCat\ChanPool\EntryPool;
use DreamCat\ChanPool\Pojo\ChannelPoolConfig;
use Psr\Log\LoggerInterface;
use Swoole\Coroutine\Channel;

/**
 * 通过通道实现的实体共享池
 * @author vijay
 */
class ChannelEntryPool implements EntryPool
{
    /** @var Channel 通道 */
    private $pools;
    /** @var float|null 超时时间 */
    private $timeSecond;
    /** @var LoggerInterface 日志记录器 */
    private $logger;

    /**
     * ChannelEntryPool constructor.
     * @param ChannelPoolConfig $config 池子配置
     */
    public function __construct(ChannelPoolConfig $config)
    {
        $size = $config->getSize();
        $this->logger = $config->getLogger();

        $poolEntryFactory = $config->getPoolEntryFactory();
        $this->timeSecond = $config->getTimeSecond();
        $this->pools = new Channel($size);
        for ($idx = 0; $idx < $size; ++$idx) {
            $this->put($poolEntryFactory->createEntry());
        }
        $this->logger->debug("连接池已建立，尺寸为{$size}，元素工厂为" . get_class($poolEntryFactory));
    }

    /**
     * 将对象放回池子
     * @param mixed $entry 对象
     * @return void
     */
    public function put($entry): void
    {
        $this->pools->push($entry, $this->timeSecond);
        $this->logger->debug("连接池得到一个对象，类型为" . get_class($entry));
    }

    /**
     * 获取对象
     * @return mixed 对象
     */
    public function get()
    {
        $this->logger->debug("连接池准备取出一个对象");
        return $this->pools->pop($this->timeSecond);
    }
}

# end of file
